#!/usr/bin/python
#-*- coding:utf-8 -*-

# value_bar.py
#
# Copyright (c) 2007 Marcelo Lira dos Santos
#
# Author: Marcelo Lira dos Santos <setanta@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA

import pygtk
pygtk.require('2.0')
import gtk
import gobject
import cairo

class ValueBar(gtk.DrawingArea):
    '''
    ValueBar
    Copyright (C) 2007 Marcelo Lira dos Santos

    Licensed under the terms of the GNU Lesser General Public License:
            http://www.opensource.org/licenses/lgpl-license.php
    '''

    __gsignals__ = {
            'realize': 'override',
            'expose-event' : 'override',
    }

    __gproperties__ = {
            'max-value' : \
                    (int, 'maximum value',
                    'maximum value represented on the bar',
                    0, 1000, 0, gobject.PARAM_READWRITE),
            'value' : \
                    (int, 'current value',
                    'current value represented on the bar',
                    0, 1000, 0, gobject.PARAM_READWRITE),
            'bg-color' : \
                    (gtk.gdk.Color, 'background color',
                    'color for the background of the bar',
                    gobject.PARAM_READWRITE),
            'fg-color' : \
                    (gtk.gdk.Color, 'foreground color',
                    'color for the background of the bar',
                    gobject.PARAM_READWRITE),
            'text-color' : \
                    (gtk.gdk.Color, 'text color',
                    'color for the text to be displayed on the bar',
                    gobject.PARAM_READWRITE),
    }

    def __init__(self, max_value, full=True):
        gtk.DrawingArea.__init__(self)

        self.max_value = max_value

        if full:
            self.value = max_value
        else:
            self.value = 0

        style = self.get_style()

        self.fg_color = style.bg[gtk.STATE_SELECTED]
        self.bg_color = style.fg[gtk.STATE_SELECTED]
        self.text_color = style.text[gtk.STATE_SELECTED]

        self.set_size_request(-1, 22)

    def do_get_property(self, property):
        if property.name == 'max-value':
            return self.max_value
        elif property.name == 'value':
            return self.value
        elif property.name == 'bg-color':
            return self.bg_color
        elif property.name == 'fg-color':
            return self.fg_color
        elif property.name == 'text-color':
            return self.text_color
        else:
            raise AttributeError, 'unknown property %s' % property.name

    def do_set_property(self, property, value):
        if property.name == 'max-value':
            self.max_value = value
            self.force_redraw()
        elif property.name == 'value':
            self.value = value
            self.force_redraw()
        elif property.name == 'bg-color':
            self.bg_color = value
        elif property.name == 'fg-color':
            self.fg_color = value
        elif property.name == 'text-color':
            self.text_color = value
        else:
            raise AttributeError, 'unknown property %s' % property.name
        self.queue_draw()

    def do_realize(self):
        self.set_flags(self.flags() | gtk.REALIZED)

        events = gtk.gdk.EXPOSURE_MASK | gtk.gdk.BUTTON_PRESS_MASK | \
                 gtk.gdk.POINTER_MOTION_MASK

        self.window = gtk.gdk.Window(self.get_parent_window(),
                                     x=self.allocation.x,
                                     y=self.allocation.y,
                                     width=self.allocation.width,
                                     height=self.allocation.height,
                                     window_type=gtk.gdk.WINDOW_CHILD,
                                     wclass=gtk.gdk.INPUT_OUTPUT,
                                     visual=self.get_visual(),
                                     colormap=self.get_colormap(),
                                     event_mask=self.get_events() | events)

        self.window.set_user_data(self)
        self.style.attach(self.window)
        self.style.set_background(self.window, gtk.STATE_SELECTED)


    def do_expose_event(self, event):
        context = self.window.cairo_create()
        context.rectangle(event.area.x, event.area.y,
                          event.area.width, event.area.height)
        context.clip()

        self.draw(context)

        return False


    def force_redraw(self, all=False):
        rect = self.get_allocation()
        self.queue_draw_area(rect.x, rect.y, rect.width, rect.height)


    def draw(self, context, redraw=False):
        rect = self.get_allocation()
        x = rect.width / 2
        y = rect.height / 2

        frac = float(self.value) / float(self.max_value)
        width = int(frac * rect.width)

        # Background
        context.new_path()
        context.set_source_color(self.bg_color)
        context.move_to(width, 0)
        context.line_to(rect.width, 0)
        context.line_to(rect.width, rect.height)
        context.line_to(width, rect.height)
        context.fill_preserve()

        # Bar
        context.new_path()
        context.set_source_color(self.fg_color)
        context.move_to(0, 0)
        context.line_to(width, 0)
        context.line_to(width, rect.height)
        context.line_to(0, rect.height)
        context.fill_preserve()

        # Show value
        context.new_path()
        context.set_source_color(self.text_color)
        descent = context.font_extents()[1]
        print 'max_x qq coisa: ',
        print context.font_extents()
        context.move_to(x, y + descent)
        context.show_text('%d' % self.value)


    def __change_value(self, value):
        self.value += value
        if self.value > self.max_value:
            self.value = self.max_value
        self.force_redraw()

    def increase(self):
        self.__change_value(1)

    def decrease(self):
        self.__change_value(-1)


def test():
    window = gtk.Window()
    window.set_title('ValueBar')
    window.set_default_size(500, 400)

    vbox = gtk.VBox()

    bar = ValueBar(15, False)
    bar.set_size_request(-1, 60)
    bar.value = 8
    vbox.pack_start(bar, True)

    def do_increase(widget):
        bar.increase()

    button1 = gtk.Button('increase')
    button1.connect('clicked', do_increase)
    vbox.pack_start(button1)

    def do_decrease(widget):
        bar.decrease()

    button2 = gtk.Button('decrease')
    button2.connect('clicked', do_decrease)
    vbox.pack_start(button2)

    window.add(vbox)
    window.connect('delete-event', gtk.main_quit)
    window.show_all()
    gtk.main()

if __name__ == '__main__':
    test()
